<template>
  <div class="photo-wall-container">
    <div class="blank-top"></div>
    <div class="box" ref="box" @pointerdown="startDrag" :style="{ transform: `rotateX(${-tY}deg) rotateY(${tX}deg)` }">

      <div v-for="(row, rowIndex) in rows" :key="rowIndex" class="box-imgs" :ref="el => setRowRef(el, rowIndex)"
        :style="{ animationPlayState: autoRotateState }">

        <img v-for="(img, imgIndex) in row" :key="imgIndex" :src="img" :alt="`示例图片${rowIndex * 28 + imgIndex + 1}`"
          :style="getImgStyle(imgIndex, row.length)" @click="showModal(img)">
      </div>
    </div>

    <div class="modal" :class="{ show: showModalState }" @click.self="closeModal">
      <span class="close" @click="closeModal">&times;</span>
      <img class="modal-content" :src="currentImg" ref="modalImg">
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { findPhotoWallPageList } from "@/api/photoWall.js";

// 响应式状态
const radius = ref(560)
const tX = ref(0)
const tY = ref(30)
const autoRotate = ref(true)
const showModalState = ref(false)
const currentImg = ref('')
const box = ref(null)
const rows = reactive([])
const rowRefs = reactive([])
// 生成图片URL
const generateImages = async (row, count) => {
  return await getImgData(row + 1, count)
}
// 获取图片列表
const getImgData = async (pageNow, pageSize) => {
  let result = await findPhotoWallPageList({
    pageModel: {
      pageNow: pageNow,
      pageSize: pageSize,
    }
  });
  if (result.code === 200) {
    let dataList = result.data.list.dataList;
    let urlList = dataList.map(item => item.url);
    return urlList;
  }
  return []
}
// 自动旋转状态
const autoRotateState = computed(() => autoRotate.value ? 'running' : 'paused')
// 设置每排元素的引用
const setRowRef = (el, index) => {
  if (el) rowRefs[index] = el
}
// 计算图片位置
const getImgStyle = (index, total) => {
  return {
    transform: `rotateY(${index * (360 / total)}deg) translateZ(${radius.value}px)`
  }
}
// 更新所有图片位置
const updateAllImages = () => {
  rowRefs.forEach((rowEl, rowIndex) => {
    const imgs = rowEl?.querySelectorAll('img') || []
    imgs.forEach((img, imgIndex) => {
      img.style.transform = `rotateY(${imgIndex * (360 / imgs.length)}deg) translateZ(${radius.value}px)`
    })
  })
}
// 拖拽相关变量
let startX, startY, endX, endY, desX = 0, desY = 0
let dragInterval = null
// 开始拖拽
const startDrag = (e) => {
  e.preventDefault()
  clearInterval(dragInterval)
  startX = e.clientX
  startY = e.clientY
  autoRotate.value = false

  const onPointerMove = (e) => {
    endX = e.clientX
    endY = e.clientY
    desX = endX - startX
    desY = endY - startY
    tX.value += desX * 0.1
    tY.value += desY * 0.1

    // 限制X轴旋转角度
    if (tY.value > 180) tY.value = 180
    if (tY.value < 0) tY.value = 0

    startX = endX
    startY = endY
  }

  const onPointerUp = () => {
    // 惯性滑动效果
    dragInterval = setInterval(() => {
      desX *= 0.95
      desY *= 0.95

      if (Math.abs(desX) < 0.5 && Math.abs(desY) < 0.5) {
        clearInterval(dragInterval)
        autoRotate.value = true
        return
      }

      tX.value += desX * 0.1
      tY.value += desY * 0.1

      // 限制X轴旋转角度
      if (tY.value > 180) tY.value = 180
      if (tY.value < 0) tY.value = 0
    }, 16)

    document.removeEventListener('pointermove', onPointerMove)
    document.removeEventListener('pointerup', onPointerUp)
  }
  document.addEventListener('pointermove', onPointerMove)
  document.addEventListener('pointerup', onPointerUp)
}

// 鼠标滚轮缩放
const handleWheel = (e) => {
  e.preventDefault()
  const delta = e.deltaY > 0 ? -20 : 20
  radius.value += delta
  // 限制半径范围
  radius.value = Math.max(300, Math.min(1000, radius.value))
  updateAllImages()
}
// 显示模态框
const showModal = (img) => {
  currentImg.value = img
  showModalState.value = true
  autoRotate.value = false
}
// 关闭模态框
const closeModal = () => {
  showModalState.value = false
  autoRotate.value = true
}

// 初始化
onMounted(async () => {
  // 初始化图片数据
  for (let i = 0; i < 4; i++) {
    rows.push(await generateImages(i, 28))
  }
  document.addEventListener('wheel', handleWheel, { passive: false })
  // 初始位置设置
  tX.value = 0
  tY.value = 30
  radius.value = 560
  autoRotate.value = true
  updateAllImages()
})
onUnmounted(() => {
  // 组件卸载时，移除document上的滚轮事件监听
  document.removeEventListener('wheel', handleWheel, { passive: false })
})
</script>

<style scoped lang="less">
.photo-wall-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background-color: #000;
  perspective: 500px;
  perspective-origin: center;
}

.blank-top {
  height: 20vh;
}

.box {
  transform-style: preserve-3d;
  height: 100%;
}

.box-imgs {
  transform-style: preserve-3d;
  position: relative;
  margin: auto;
  width: 120px;
  height: 140px;
  animation: autoRotate 200s infinite linear;
}

.box-imgs:not(:first-child) {
  margin-top: 6px;
}

.box-imgs img {
  transform-style: preserve-3d;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: transform 0.3s ease;
}

.box-imgs img:hover {
  transform: scale(1.05);
}

.box-imgs:last-child img {
  //-webkit-box-reflect: below 10px linear-gradient(transparent, transparent, #0005);
}

@keyframes autoRotate {
  from {
    transform: rotateY(0deg);
  }

  to {
    transform: rotateY(360deg);
  }
}

.modal {
  display: none;
  position: fixed;
  z-index: 1000;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.9);
  justify-content: center;
  align-items: center;
}

.modal.show {
  display: flex;
}

.modal-content {
  max-width: 80%;
  max-height: 80%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
}

.close {
  position: absolute;
  top: 20px;
  right: 30px;
  color: #fff;
  font-size: 40px;
  font-weight: bold;
  cursor: pointer;
  transition: 0.3s;
}

.close:hover,
.close:focus {
  color: #bbb;
  text-decoration: none;
}
</style>
